home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / libsock / slp.c < prev    next >
C/C++ Source or Header  |  1997-06-15  |  5KB  |  211 lines

  1. /* slp.c:  Pilot SLP protocol
  2.  *
  3.  * (c) 1996, D. Jeff Dionne.
  4.  * Much of this code adapted from Brian J. Swetland <swetland@uiuc.edu>
  5.  *
  6.  * This is free software, licensed under the GNU Public License V2.
  7.  * See the file COPYING for details.
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include "pi-source.h"
  12. #include "pi-socket.h"
  13. #include "pi-slp.h"
  14.  
  15. /* Build and queue up an SLP packet to be transmitted */
  16.  
  17. int slp_tx(struct pi_socket *ps, struct pi_skb *nskb, int len)
  18. {
  19.   struct pi_skb *skb;
  20.   struct slp *slp;
  21.  
  22.   unsigned int i;
  23.   unsigned int n;
  24.  
  25.   slp = (struct slp *)nskb->data;
  26.  
  27.   slp->_be  = 0xbe;
  28.   slp->_ef  = 0xef;
  29.   slp->_ed  = 0xed;
  30.   slp->dest = nskb->dest;
  31.   slp->src  = nskb->source;
  32.   slp->type = nskb->type;
  33.   slp->dlen = htons(len);
  34.   slp->id   = nskb->id;
  35.  
  36.   for (n = i = 0; i<9; i++) n += nskb->data[i];
  37.   slp->csum = 0xff & n;
  38.  
  39.   set_short(&nskb->data[len+10], crc16(nskb->data, len+10));
  40.   
  41.   nskb->len = len+12;
  42.   nskb->next = (struct pi_skb *)0;
  43.  
  44.   ps->busy++;
  45.   if (!ps->txq) ps->txq = nskb;
  46.   else {
  47.     for (skb = ps->txq; skb->next; skb=skb->next);
  48.     skb->next = nskb;
  49.   }
  50.   ps->busy--;
  51.  
  52.   dph(nskb->data);
  53.   slp_dump(nskb,1);
  54.  
  55.   ps->tx_packets++;
  56.   return 0;
  57. }
  58.  
  59. /* Sigh.  SLP is a really broken protocol.  It has no proper framing, so
  60.    it makes a proper "device driver" layer impossible.  There ought to be
  61.    a layer below SLP that reads frames off the wire and passes them up.
  62.    Insted, all we can do is have the device driver give us bytes and SLP
  63.    has to keep a pile of status info while it builds frames for itself.
  64.    So here's the code that does that. */
  65.  
  66. int slp_rx(struct pi_socket *ps)
  67. {
  68.   int i;
  69.   int v;
  70.   struct pi_skb *skb;
  71.  
  72.   if (!ps->mac->state) {
  73.     ps->mac->expect = 1;
  74.     ps->mac->state = 1;
  75.     ps->mac->rxb = (struct pi_skb *)malloc(sizeof(struct pi_skb));
  76.     ps->mac->rxb->next = (struct pi_skb *)0;
  77.     ps->mac->buf = ps->mac->rxb->data;
  78.     return 0;
  79.   }
  80.  
  81.   v = 0xff & (int) *ps->mac->buf;
  82.  
  83.   switch(ps->mac->state) {
  84.  
  85.   case 1:
  86.     if (v == 0xbe) { 
  87.       ps->mac->state++;
  88.       ps->mac->expect = 1;
  89.       ps->mac->buf++;
  90.     }
  91.     else ps->mac->expect = 1;
  92.     break;
  93.  
  94.   case 2:
  95.     if (v == 0xef) { 
  96.       ps->mac->state++;
  97.       ps->mac->expect = 1;
  98.       ps->mac->buf++;
  99.     }
  100.     break;
  101.  
  102.   case 3:
  103.     if (v == 0xed) { 
  104.     /* OK.  we think we're sync'ed, so go for the rest of the header */
  105.       ps->mac->state++;
  106.       ps->mac->expect = 7;
  107.       ps->mac->buf++;
  108.     }
  109.     break;
  110.  
  111.   case 4:
  112.     /* read in the whole SLP header. */
  113.     for (v = i = 0; i<9; i++) v += ps->mac->rxb->data[i];
  114.  
  115.     dph(ps->mac->rxb->data);
  116.  
  117.     if ((v & 0xff) == ps->mac->rxb->data[9]) {
  118.       ps->mac->state++;
  119.       ps->mac->rxb->len = 12+ get_short(&ps->mac->rxb->data[6]);
  120.       ps->mac->expect = ps->mac->rxb->len - 10;
  121.       ps->mac->buf += 7;
  122.     }
  123.     break;
  124.  
  125.   case 5:
  126.     /* that should be the whole packet. */
  127.     v = crc16(ps->mac->rxb->data, ps->mac->rxb->len - 2);
  128.  
  129.     if ((v == 
  130.     get_short(&ps->mac->rxb->data[ps->mac->rxb->len - 2]))
  131. #if 0
  132.     || (0xbeef == 
  133.     get_short(&ps->mac->rxb->data[ps->mac->rxb->len - 2]))
  134. #endif
  135.     ) {
  136.  
  137.       ps->mac->rxb->dest = ps->mac->rxb->data[3];
  138.       ps->mac->rxb->source = ps->mac->rxb->data[4];
  139.       ps->mac->rxb->type = ps->mac->rxb->data[5];
  140.       ps->mac->rxb->id = ps->mac->rxb->data[8];
  141.       /*ps->xid = ps->mac->rxb->data[8];
  142.       ps->laddr.pi_port = ps->mac->rxb->data[3];
  143.       ps->raddr.pi_port = ps->mac->rxb->data[4]; 
  144.       ps->protocol = ps->mac->rxb->data[5]; XXX */
  145.       
  146.       /* hack to ignore LOOP packets... */
  147.  
  148.       if (ps->mac->rxb->data[5] == 3 /*PI_PF_LOOP*/) {
  149.     ps->mac->expect = 1;
  150.     ps->mac->state = 1;
  151.     ps->mac->rxb->next = (struct pi_skb *)0;
  152.     ps->mac->buf = ps->mac->rxb->data;
  153.       } else {
  154.     if (!ps->rxq) ps->rxq = ps->mac->rxb;
  155.     else {
  156.  
  157.       for (skb = ps->rxq; skb->next; skb=skb->next);
  158.       skb->next = ps->mac->rxb;
  159.     }
  160.     ps->mac->state = 0;
  161.       }
  162.       ps->rx_packets++;
  163.     } else {
  164. #ifdef DEBUG
  165.       fprintf(stderr,"my crc=0x%.4x your crc=0x%.4x\n", v, get_short((&ps->mac->rxb->data[ps->mac->rxb->len - 2])));
  166. #endif
  167.     }
  168.     slp_dump(ps->mac->rxb,0);
  169.     break;
  170.  
  171.   default:
  172.     break;
  173.   }
  174.  
  175.   if (ps->mac->state && (!ps->mac->expect)) {
  176.  
  177. #ifdef DEBUG
  178.     fprintf(stderr, "SLP RX: error, state %d \n",ps->mac->state);
  179. #endif
  180.  
  181.     ps->mac->state = ps->mac->expect = 1;
  182.     ps->mac->buf = ps->mac->rxb->data;
  183.     ps->rx_errors++;
  184.   }
  185.  
  186.   return 0;
  187. }
  188.  
  189. void slp_dump(struct pi_skb *skb, int rxtx)
  190. {
  191. #ifdef DEBUG
  192.   fprintf(stderr,"SLP %s %d->%d len=0x%.4x Prot=%d ID=0x%.2x\n",
  193.       rxtx ? "TX" : "RX" ,
  194.       skb->data[4],skb->data[3],
  195.       get_short(&skb->data[6]),
  196.       skb->data[5],skb->data[8]);
  197. #endif
  198. }
  199.  
  200.  
  201. void dph(unsigned char *d)
  202. {
  203. #ifdef DEBUG
  204.   int i;
  205.  
  206.   fprintf(stderr,"SLP HDR [");
  207.   for (i=0;i<10;i++) fprintf (stderr," 0x%.2x",0xff & d[i]);
  208.   fprintf(stderr,"]\n");
  209. #endif
  210. }
  211.